package com.spring.util;

import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.util.CollectionUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cloopen.rest.sdk.CCPRestSmsSDK;
import com.spring.common.allocation.AliSMSExposer;
import com.spring.common.allocation.RLSMSExposer;
import com.spring.common.allocation.SmsTemp;
import com.taobao.api.request.AlibabaAliqinFcSmsNumSendRequest;
import com.taobao.api.response.AlibabaAliqinFcSmsNumSendResponse;

/**
 * Created by liuyang on 2016/7/12.
 */
public class AliSmsService {
	protected final static Logger logger = Logger.getLogger(AliSmsService.class);

	// smsId
	public static final String APP_REGISTER_TEMP = "SMS_15380258"; // app注册短信模板（完成）

	public static final String APP_CODE_TEMP = "SMS_15400185"; // 动态验证码模板（完成）

	public static final String DOCTOR_AUTH_PASS_TEMPID = "SMS_12865289"; // 医生身份认证通过短信通知（完成）

//	public static final String DOCTOR_AUTH_NOT_PASS_TEMPID = "SMS_12790230";// 医生身份认证不通过短信通知（完成）
	public static final String DOCTOR_AUTH_NOT_PASS_TEMPID = "SMS_34910132";// 医生身份认证不通过短信通知（完成）
	

	public static final String FOLLOW_PATIENT_TEMPID = "SMS_12921629"; // 医生邀请随访患者短信（完成）

	public static final String ADMIN_RESET_PASSWORD = "SMS_12905930"; // 后台密码重置短信（完成）

	public static final String CREATE_ORDER_TEMPID = "SMS_16820037";// 购买图文订单后短信提醒（完成）

	public static final String TEXT_ORDER_STATUS_REFUND = "SMS_26045539"; // 图文订单状态改为退款中短信提醒（完成）
																			// SMS_16725275
																			// 已废弃

	public static final String TEXT_ORDER_STATUS_STAY_REFUND = "SMS_16720369"; // 图文订单状态自动改为待退款短信提醒（完成）

	public static final String WX_DOCTOR_REG_TEMPID = "SMS_18345677";// 微信医生注册成功通知短信（完成）

	/*-----------------V2.76  电话订单-------------------------------*/
	public static final String TEL_REFUND_SMS = "SMS_25980428";// 电话退款短信--患者端
	public static final String CREATE_TEL_ORDER_PATIENT = "SMS_26090019";// 患者购买医生电话服务短信--患者端
	public static final String CREATE_TEL_ORDER_DOCTOR = "SMS_25880507";// 患者购买医生电话服务短信--医生端
	public static final String CUSTOMER_SERVICE_CONFIRMATION_PATIENT = "SMS_25885434";// 客服确认通话时间--患者端
	public static final String CUSTOMER_SERVICE_CONFIRMATION_DOCTOR = "SMS_26045540";// 客服确认通话时间--医生端

	/*-----------------V2.76  机构订单-------------------------------*/
	public static final String INSTITUTION_CONFIRMATION = "SMS_25890463";// 下单后机构确认订单的短信提醒
	public static final String INSTITUTION_ORDER_REJECT = "SMS_25955405";// 下单后被拒绝的短信(非0元)
	public static final String INSTITUTION_ORDER_REJECT_0 = "SMS_32600117";// 下单后被拒绝的短信(0元)
	public static final String INSTITUTION_ORDER_BOOK_TIME_REMIND = "SMS_25930411";// 约定的咨询时间的前两个小时的短信提醒

	public static final Map<String, String> smsMap = new HashMap<>();

	static {
		// app注册短信模板
		smsMap.put(APP_REGISTER_TEMP, SmsTemp.APP_REGISTER_TEMP);
		// 动态验证码模板
		smsMap.put(APP_CODE_TEMP, SmsTemp.APP_CODE_TEMP);
		// 医生身份认证通过短信通知
		smsMap.put(DOCTOR_AUTH_PASS_TEMPID, SmsTemp.DOCTOR_AUTH_PASS_TEMPID);
		// 医生身份认证不通过短信通知
		smsMap.put(DOCTOR_AUTH_NOT_PASS_TEMPID, SmsTemp.DOCTOR_AUTH_NOT_PASS_TEMPID);
		// 医生邀请随访患者短信
		smsMap.put(FOLLOW_PATIENT_TEMPID, SmsTemp.FOLLOW_PATIENT_TEMPID);
		// 后台密码重置短信
		smsMap.put(ADMIN_RESET_PASSWORD, SmsTemp.ADMIN_RESET_PASSWORD);
		// 购买图文订单后短信提醒
		smsMap.put(CREATE_ORDER_TEMPID, null);
		// 图文订单状态改为退款中短信提醒
		smsMap.put(TEXT_ORDER_STATUS_REFUND, null);
		// 图文订单状态自动改为待退款短信提醒
		smsMap.put(TEXT_ORDER_STATUS_STAY_REFUND, null);
		// 微信医生注册成功通知短信
		smsMap.put(WX_DOCTOR_REG_TEMPID, SmsTemp.WX_DOCTOR_REG_TEMPID);
		
		/*-----------------V2.76  电话订单-------------------------------*/
		//电话退款短信--患者端
		smsMap.put(TEL_REFUND_SMS, SmsTemp.TEL_REFUND_SMS);
		// 患者购买医生电话服务短信--患者端
		smsMap.put(CREATE_TEL_ORDER_PATIENT,SmsTemp.CREATE_TEL_ORDER_PATIENT);
		// 患者购买医生电话服务短信--医生端
		smsMap.put(CREATE_TEL_ORDER_DOCTOR, SmsTemp.CREATE_TEL_ORDER_DOCTOR);
		// 客服确认通话时间--患者端
		smsMap.put(CUSTOMER_SERVICE_CONFIRMATION_PATIENT, SmsTemp.CUSTOMER_SERVICE_CONFIRMATION_PATIENT);
		// 客服确认通话时间--医生端
		smsMap.put(CUSTOMER_SERVICE_CONFIRMATION_DOCTOR,SmsTemp.CUSTOMER_SERVICE_CONFIRMATION_DOCTOR);
		
		/*-----------------V2.76  机构订单-------------------------------*/
		// 下单后机构确认订单的短信提醒
		smsMap.put(INSTITUTION_CONFIRMATION, SmsTemp.INSTITUTION_CONFIRMATION);
		// 下单后被拒绝的短信(非0元)
		smsMap.put(INSTITUTION_ORDER_REJECT, SmsTemp.INSTITUTION_ORDER_REJECT);
		// 下单后被拒绝的短信(0元)
		smsMap.put(INSTITUTION_ORDER_REJECT_0, SmsTemp.INSTITUTION_ORDER_REJECT_0);
		
		
		// 约定的咨询时间的前两个小时的短信提醒
		smsMap.put(INSTITUTION_ORDER_BOOK_TIME_REMIND, SmsTemp.INSTITUTION_ORDER_BOOK_TIME_REMIND);

	}

	/**
	 * 生成指定长度位数验证码
	 *
	 * @param length
	 *            长度
	 * @return string
	 */
	public static String getActivatingKey(int length) {
		String[] str = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
		StringBuilder buffer = new StringBuilder("");
		Random r = new Random();
		for (int i = 0; i < length; i++) {
			buffer.append(str[r.nextInt(str.length)]);
		}

		return buffer.toString();

	}

	/**
	 * 阿里大鱼短信通道
	 *
	 * @param mobile
	 * @param smsTempMessage
	 * @param smsTempId
	 */
	public static boolean aliDaYusendSms(String mobile, String smsTempMessage, String smsTempId) throws Exception {

		AlibabaAliqinFcSmsNumSendRequest req = AliSMSExposer.getAliSMSApi();
		// 【可选】，公共回传参数，在“消息返回”中会透传回该参数；举例：用户可以传入自己下级的会员ID，在消息返回时，
		// 该会员ID会包含在内，用户可以根据该会员ID识别是哪位会员使用了你的应用
		req.setExtend("");
		// 【必须】短信类型，传入值请填写normal
		req.setSmsType("normal");
		// 【必须】短信签名，传入的短信签名必须是在阿里大鱼“管理中心-短信签名管理”中的可用签名。
		// 如“阿里大鱼”已在短信签名管理中通过审核，则可传入”阿里大鱼“（传参时去掉引号）作为短信签名。短信效果示例：【阿里大鱼】欢迎使用阿里大鱼服务。
		req.setSmsFreeSignName("好心情");
		// 【可选】短信模板变量，传参规则{"key":"value"}，key的名字须和申请模板中的变量名一致，
		// 多个变量之间以逗号隔开。示例：针对模板“验证码${code}，您正在进行${product}身份验证，打死不要告诉别人哦！”，
		// 传参时需传入{"code":"1234","product":"alidayu"}
		// req.setSmsParamString("{\"code\":\"1234\",\"product\":\"您在好心情的\",\"item\":\"阿里大鱼\"}");
		// {"product":"好心情医疗平台验证码","item":"阿里大鱼","code":"123456"}
		req.setSmsParamString(smsTempMessage);
		// 【必须】短信接收号码。支持单个或多个手机号码，传入号码为11位手机号码，不能加0或+86。群发短信需传入多个号码，
		// 以英文逗号分隔，一次调用最多传入200个号码。示例：18600000000,13911111111,13322222222
		req.setRecNum(mobile);
		// 【必须】短信模板ID，传入的模板必须是在阿里大鱼“管理中心-短信模板管理”中的可用模板。示例：SMS_585014
		req.setSmsTemplateCode(smsTempId);
		AlibabaAliqinFcSmsNumSendResponse rsp = null;
		rsp = AliSMSExposer.client.execute(req);
		logger.debug("手机号："+mobile+",发送模板："+smsTempId+",发送时间："+DateUtils.formatTime(new Date())+"阿里大鱼短信发送回执：" + JSON.toJSONString(rsp));
		JSONObject jsonObject = JSON.parseObject(rsp.getBody());
		boolean resultMsg = jsonObject.getJSONObject("alibaba_aliqin_fc_sms_num_send_response").getJSONObject("result")
				.getBoolean("success");
		return resultMsg;
	}

	public static boolean rlSmsSend(String mobile, String smsTempId, String[] smsTempMsg) {
		HashMap<String, Object> result = null;
		CCPRestSmsSDK ccpRestSDKApi = RLSMSExposer.getCCPRestSDKApi();
		result = ccpRestSDKApi.sendTemplateSMS(mobile, smsTempId, smsTempMsg);
		logger.debug("手机号："+mobile+",发送模板："+smsTempId+",发送时间："+DateUtils.formatTime(new Date())+"荣联发送回执：" + JSON.toJSONString(result));
		if ("000000".equals(result.get("statusCode"))) {
			// 正常返回输出data包体信息（map）
			HashMap<String, Object> data = (HashMap<String, Object>) result.get("data");
			Set<String> keySet = data.keySet();
			for (String key : keySet) {
				Object object = data.get(key);
			}
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 发送短信（最新）2016-11-16
	 * 
	 * @param mobile
	 * @param map
	 * @param smsTempId
	 * @return
	 */
	public static boolean sendSMS(String mobile, LinkedHashMap<String, String> map, String smsTempId) {
		boolean send = false;
		logger.debug("手机号："+mobile+",发送模板："+smsTempId+",发送时间："+DateUtils.formatTime(new Date()));
		try {
			String smsParamString = null;
			if (!CollectionUtils.isEmpty(map)) {
				smsParamString = JSONObject.toJSONString(map);
			}
			send = aliDaYusendSms(mobile, smsParamString, smsTempId);
			logger.debug("阿里大鱼短信发送成功...");
		} catch (Exception e) {
			logger.error("阿里大鱼短信发送失败，准备切换到荣联...");
			String rlTempId = smsMap.get(smsTempId);
			if (StringUtils.isNotBlank(rlTempId)) {
				String[] smsTempMsg = null;
				if(map!=null){
					smsTempMsg=  new String[] {};
					smsTempMsg =map.values().toArray(smsTempMsg);
				}
				send = rlSmsSend(mobile, rlTempId, smsTempMsg);
				if (!send) {
					logger.error(DateUtil.getCurrentSimpleDate() + "，手机号码：" + mobile + "，阿里大鱼短信发送失败，荣联也发送失败...");
				} else {
					logger.debug("荣联短信发送成功...");
				}

			} else {
				logger.error(DateUtil.getCurrentSimpleDate() + "，手机号码：" + mobile + "，阿里大鱼短信发送失败，切换到荣联失败，没有对应的短信模板...");
			}
		}
		return send;

	}

	public static void main(String[] args) {
		LinkedHashMap<String, String> map = null;
		System.out.println(JSONObject.toJSONString(map) + "");
	}

}